<?php

use Welcomescreen\Agavi\Model;
use Welcomescreen\Exception;
use Welcomescreen\Objects;

class UserManagerModel extends Model\BaseModel implements \AgaviISingletonModel {
	/**
	 * @var array(string => Welcomescreen\Objects\User)
	 */
	protected $users;
	
	/**
	 * Loads all users from the user store
	 */
	protected function loadUsers() {
		if($this->users !== null) {
			return;
		}
		
		$this->users = array();
		$userData = require(\AgaviConfigCache::checkConfig(\AgaviConfig::get('org.welcomescreen.system.config_dir') . '/users.xml'));
		foreach($userData['users'] as $name => $data) {
			$this->users[$name] = new Objects\User($name, $data['password']);
		}
	}
	
	/**
	 * Checks if a user with the given name exists.
	 *
	 * @param string $name 
	 * @return bool
	 */
	public function hasUser($name) {
		$this->loadUsers();
		return isset($this->users[$name]);
	}
	
	/**
	 * Retrieves a user (by name).
	 * 
	 * @throws NonexistentObjectException If the user doesn't exist.
	 * @param string $name
	 * @return Welcomescreen\Objects\User
	 */
	public function getUser($name) {
		$this->loadUsers();
		if(isset($this->users[$name])) {
			return $this->users[$name];
		}
		throw new Exception\NonexistentObjectException('The user with the name "' . $name . '" does not exist');
	}
	
	/**
	 * Adds a new user.
	 * 
	 * @throws DuplicateObjectException If the user already exists.
	 * @throws ConfigurationFormatException If the users.xml is not in the expected format.
	 * @param Welcomescreen\Objects\User $user
	 */
	public function addUser(Objects\User $user) {
		$this->loadUsers();
		if($this->hasUser($user->getName())) {
			throw new Exception\NonexistentObjectException('The user with the name "' . $user->getName() . '" does already exist');
		}
		
		$usersXmlPath = \AgaviConfig::get('org.welcomescreen.system.config_dir') . '/users.xml';
		$doc = new \DOMDocument();
		$doc->preserveWhiteSpace = false;
		$doc->formatOutput = true;
		
		$doc->load($usersXmlPath);
		
		$xpath = new \DOMXPath($doc);
		$xpath->registerNamespace('a', 'http://agavi.org/agavi/1.0/config');
		$usersNodeList = $xpath->query('//a:users');
		if($usersNodeList->length == 0) {
			throw new Exception\ConfigurationFormatException('The users.xml file is missing the <users> tag');
		}
		
		$usersNode = $usersNodeList->item(0);
		$userNode = $doc->createElement('user');
		$userNode->setAttribute('name', $user->getName());
		$userNode->setAttribute('password', $user->getPassword());
		$usersNode->appendChild($userNode);
		
		$doc->save($usersXmlPath);
		
		$this->users[$user->getName()] = $user;
	}
}

?>